/**
 * 
 */
package mblog.web.controller.front.posts;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import mblog.core.context.AppContext;
import mblog.core.planet.PostPlanet;
import mblog.core.pojos.Post;
import mblog.core.pojos.User;
import mblog.core.utils.BeanMapUtils;
import mblog.web.controller.BaseController;
import mblog.web.upload.Repository;
import mtons.modules.pojos.Data;
import mtons.modules.pojos.Page;
import mtons.modules.pojos.UserContextHolder;
import mtons.modules.pojos.UserProfile;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.faxsun.core.persist.entity.FollowListPO;
import com.faxsun.core.service.FollowListService;
import com.faxsun.core.service.HotspotService;
import com.faxsun.core.service.IndexService;
import com.faxsun.core.service.PostService;
import com.faxsun.core.service.TagService;
import com.faxsun.core.service.UserService;
import com.faxsun.core.utils.PreviewHtmlUtils;
import com.faxsun.pojos.view.PostTable;
import com.faxsun.web.controller.FrontViewConstants;
import com.faxsun.web.pojos.FSUserProfile;
import com.faxsun.web.utils.MobileDetect;
import com.faxsun.web.endpoint.entity.PostTableJSON;

/**
 * @author langhsu
 * @author songdragon
 *
 */
@SuppressWarnings("deprecation")
@Controller
@RequestMapping("/post")
public class PostController extends BaseController {
	@Autowired
	private PostService postService;
	@Autowired
	private PostPlanet postPlanet;
	@Autowired
	private AppContext appContext;
	@Autowired
	private Repository fileRepository;
	@Autowired
	private TagService tagService;
	@Autowired
	private HotspotService hotspotService;
	@Autowired
	private IndexService indexService;
	@Autowired
	private FollowListService flService;

    @Autowired
    protected UserService userService;

	/**
	 * 用户编辑文章
	 * 
	 * @param blog
	 *            页面文章模型
	 * @param type
	 *            文章类型
	 * @param id
	 *            文章ID
	 * @param model
	 *            页面模型
	 * @return 渲染页面的View
	 */
	@RequestMapping(value = "/add", method = RequestMethod.GET)
	public String add(
			@ModelAttribute("blog") Post blog,
			@RequestParam(value = "type", required = false, defaultValue = "1") Integer type,
			@RequestParam(value = "id", required = false) Long id,
			ModelMap model) {
		blog.setType(type);
		if (id != null && id > 0L) {
			// id存在，则读取已有文章展示
			Post p = postPlanet.getPost(id);
			UserProfile up = UserContextHolder.getUserProfile();
			if (p.getAuthor().getId() == up.getId()) {
				blog = (p == null ? blog : p);
			} else {
				// 无权限
				return "redirect:/post/myblogs";
			}
		}

		model.addAttribute("navTags", tagService.listNavTags(1));
		model.addAttribute("blog", blog);
		return FrontViewConstants.VIEW_USER_POST;
	}

	/**
	 * Ajax方式保存编辑的文章
	 * 
	 * @param blog
	 * @param bindingResult
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/add", method = RequestMethod.POST)
	@ResponseBody
	public Data post(@ModelAttribute("blog") Post blog,
			BindingResult bindingResult, HttpServletRequest request) {

		Data ret = Data.failure("保存失败!请稍后重试!");
		if (blog != null) {
			if (blog.getSnapshot() != null) {
				String url = blog.getSnapshot().getOriginal();
				String contextPath = request.getContextPath();
				if (!url.startsWith(contextPath) && !StringUtils.isEmpty(url) // url以非context
																				// path相对路径开始且非空
						&& !url.startsWith("http://") // url非绝对路径
						&& !url.startsWith("https://")) {
					// url为非当前context下的相对路径,则增加context path
					url = contextPath + url;
					blog.getSnapshot().setOriginal(url);
				}
				if (url.equals(contextPath)) {
					// url 仅包含当前context path
					blog.getSnapshot().setOriginal("");
				}
			}
			// FIXME: add post status constant
			// blog.setStatus(0);
			long id = blog.getId();
			Post postDb = null;
			// 提交人和原文作者为同一人
			if (id > 0L) {
				postDb = postPlanet.getPost(id);
				UserProfile up = UserContextHolder.getUserProfile();
				if (postDb.getAuthor().getId() != up.getId()) {
					ret = Data.failure(-4, "不能修改他人文章");
					return ret;
				}
			}
			if (StringUtils.isEmpty(blog.getTitle())) {
				ret = Data.failure(-5, "请输入标题");
			} else if (StringUtils.isEmpty(blog.getContent())) {
				ret = Data.failure(-5, "请输入内容");
			} else if (blog.getType() < 0 || blog.getType() > 1) {
				ret = Data.failure(-5, "文章类型错误");
			} else {
				postPlanet.post(blog);
				ret = Data.success("保存成功!");
			}
		}
		return ret;
	}

	@RequestMapping("/delete/{id}")
	public @ResponseBody Data delete(@PathVariable Long id) {
		Data data = Data.failure("操作失败");
		if (id != null) {
			UserProfile up = UserContextHolder.getUserProfile();
			try {
				postPlanet.delete(id, up.getId());
				data = Data.success("操作成功");
			} catch (Exception e) {
				data = Data.failure(e.getMessage());
			}
		}
		return data;
	}

	@RequestMapping("/heart")
	public @ResponseBody Data heart(Long id) {
		Data data = Data.failure("操作失败");
		if (id != null) {
			try {
				postService.identityHearts(id);
				data = Data.success("操作成功,感谢您的支持!");
			} catch (Exception e) {
				data = Data.failure(e.getMessage());
			}
		}
		return data;
	}

	private static final String STATIC_KEYWORDS = "范客生活,范客资讯,智能硬件资讯,智能硬件社区,";

	/**
	 * 范客资讯显示文章
	 * 
	 * @param id
	 * @param model
	 * @return
	 */
	@RequestMapping(value = "/view/{id}")
	public String view(@PathVariable Long id, ModelMap model,
			HttpServletRequest request) {
		Post post = postPlanet.getPost(id);
		readShareInfo(post);
		model.addAttribute("post", post);

		Page hotInfoPage = wrapPage(1);
		hotInfoPage.setMaxResults(10);
		indexService.retrieveHotInfo(hotInfoPage);
		model.addAttribute("topInfos", hotInfoPage.getResults());
		model.addAttribute("recommendProducts",
				indexService.retrieveRecommendProducts(new Page(1, 4)));

		model.addAttribute(FrontViewConstants.VIEW_META_KEYWORD,
				STATIC_KEYWORDS + post.getTags());
		model.addAttribute(FrontViewConstants.VIEW_META_TITLE,
				"范客生活-" + post.getTitle());

		model.addAttribute(
				FrontViewConstants.VIEW_META_DESC,
				PreviewHtmlUtils.htmlRemoveTag(post.getSummary()
						.replace("&nbsp;", "").trim()));

		UserProfile up = UserContextHolder.getUserProfile();
        String isUserFollowed = "false";        
        
        long userId = post.getAuthor().getId();
        boolean authorized = this.authorized(userId);        
        if(authorized){
            model.addAttribute("authorized", "true");
        } else{
            //return "redirect:/";            
            model.addAttribute("authorized", "false");     

            if(up != null && up.getId() > 1){
               FollowListPO fl = flService.findFollow(userId, up.getId(), 0);//user
               if(fl != null && fl.getStatus() == 0){//followed
                  isUserFollowed = "true";
               }
            }           

            User u = userService.get(userId);
            up = new FSUserProfile(u.getId(), u.getUsername());
            up.setAvatar(u.getAvatar());
            up.setLastLogin(u.getLastLogin());
            up.setEmail(u.getEmail());
            up.setName(u.getName());
            ((FSUserProfile)up).setSignature(u.getSignature());
        }
        model.addAttribute("profile", up);
        model.addAttribute("isUserFollowed", isUserFollowed);
        model.addAttribute("userId", userId);  

        int userFollowedCount = flService.countAllMyFollowers(userId, 0);
        model.addAttribute("userFollowedCount", userFollowedCount);
        
		String viewUrl = MobileDetect.getProperView(request,
				"/views/mobile/article", FrontViewConstants.VIEW_POST);
		return viewUrl;
	}

	/**
	 * 读取post相关的关注信息，由于postplanet启用了缓存，故在此处单独加载
	 * 
	 * @param d
	 */
	private void readShareInfo(Post d) {
		long postId = d.getId();
		int followed_count = flService.countAllMyFollowers(postId,
				d.getType() + 2);
		d.setFollowsCounts(followed_count);

		int thumbsup_count = flService.countAllMyThumbsupers(postId,
				d.getType() + 2);
		d.setThumbupCounts(thumbsup_count);

		UserProfile up = UserContextHolder.getUserProfile();
		// FollowListPO fl = flService.findFollow(proTagId, 1L, 1);
		FollowListPO fl = null;
		if (up != null) {
			fl = flService.findFollow(postId, up.getId(), d.getType() + 2);
			d.setFollowerId(up.getId());
		} else {
			d.setFollowerId(1);
		}
		String pro_followed = fl == null ? "false"
				: (fl.getStatus() == 0 ? "true" : "false");
		d.setIsUserFollowed(pro_followed);
		String pro_thumbsup = fl == null ? "false" : (fl.getThumbsup() ? "true"
				: "false");
		d.setIsUserThumbsup(pro_thumbsup);
	}

	@RequestMapping(value = "/list")
	public String list(ModelMap model) {
		model.addAttribute("url", "/post/data-url");
		return FrontViewConstants.VIEW_USER_POST_LIST;
	}

	/**
	 * JSON获取Post列表数据
	 * 
	 * @param type
	 * @param pageNo
	 * @param max
	 * @param search
	 * @param field
	 * @param model
	 * @return
	 */
	@SuppressWarnings("unchecked")
	@RequestMapping(value = "/data-url", method = RequestMethod.GET)
	public @ResponseBody PostTableJSON data(
			@RequestParam(value = "type", required = false) Integer type,
			@RequestParam(value = "offset", required = false) Integer pageNo,
			@RequestParam(value = "limit", required = false) Integer max,
			@RequestParam(value = "search", required = false) String search,
			@RequestParam(value = "sort", required = false) String field,
			ModelMap model) {
		// 参数校验及转换
		if (pageNo == null) {
			pageNo = 1;
		}
		if (max == null) {
			max = 10;
		}
		pageNo = pageNo / max + 1;
		Page page = wrapPage(pageNo);
		page.setMaxResults(max);

		// TODO:按字段排序
		if (StringUtils.isEmpty(search)) {
			UserProfile up = UserContextHolder.getUserProfile();
			postService.pagingByUserId(page, up.getId(), -1);
		} else {
			// TODO:搜索结果
		}
		PostTableJSON ret = new PostTableJSON();
		ret.total = page.getTotalCount();
		ArrayList<PostTable> table = new ArrayList<PostTable>();
		for (Post post : (List<Post>) page.getResults()) {
			table.add(BeanMapUtils.copy(post));
		}
		ret.rows = table;
		return ret;
	}

	/**
	 * 
	 * @return
	 */
	@RequestMapping(value = "/myblogs")
	public String listByAuthor(
			@RequestParam(value = "offset", required = false, defaultValue = "1") Integer pageNo,
			@RequestParam(value = "limit", required = false, defaultValue = "8") Integer max,
			ModelMap model, HttpServletRequest request) {

		Page page = new Page(max);
		page.setPageNo(pageNo);
		UserProfile up = UserContextHolder.getUserProfile();

		if (up != null) {
			postService.pagingByUserIdWithoutDeleted(page, up.getId());
			model.addAttribute("totalCount", page.getTotalCount());
			model.addAttribute("totalPage", page.getPageCount());
			model.addAttribute("currentPage", page.getPageNo());
			model.addAttribute("posts", page.getResults());
			model.addAttribute("page", page);

			int currentPage = page.getPageNo();
			int startPageId = currentPage - 2 < 1 ? 1 : currentPage - 2;
			int endPageId = currentPage + 2 > page.getPageCount() ? page
					.getPageCount() : currentPage + 2;
			List<Integer> pageNums = new ArrayList<Integer>();
			for (int i = startPageId; i <= endPageId; i++) {

				pageNums.add(i);
			}
			model.addAttribute("pageNums", pageNums);
		} else {
			String referer = request.getHeader("Referer");
			if (StringUtils.isEmpty(referer)) {
				referer = "/";
			}
			return "redirect:" + referer;
		}
		return "/views/authentication/myBlogs";

	}

	@ModelAttribute("blog")
	public Post initPostForm() {
		Post post = new Post();
		return post;
	}
    
    /**
     * check if current user has required permission for action like update avatar/name
     * @param userId the user id upon which action is taken
     * @return true if authorization ok otherwise false
     */
    private boolean authorized(Long userId){
        UserProfile up = UserContextHolder.getUserProfile();
        if(up == null || up.getId() < 1 || up.getId() != userId.longValue()){
            return false;
        } else{
            return true;
        }
    }
}
